#pragma once

class FileUtils {
public:
  static void ReadFileMapAndReset(
    const std::string& path, std::map<std::string, int>& data, int reset = 0) {
    std::ifstream in(path);
    std::string line;
    if (in) {
      while (std::getline(in, line)) {
        data[line] = reset;
      }
    }
  }

  static void ReadFileMapAndFilter(
    const std::string& path, const std::map<std::string, int>& base_data,
    std::map<std::string, int>& data) {
    std::ifstream in(path);
    std::string line;
    if (in) {
      while (std::getline(in, line)) { 
        auto it = base_data.find(line);
        if (it == base_data.end())
          assert(false);
        else
          data[it->first] = it->second;
      }
    }
  }

  static void ReadFileMapAndPlus(
    const std::string& path, std::map<std::string, int>& data) {
    std::ifstream in(path);
    std::string line;
    if (in) {
      while (std::getline(in, line)) {
        auto it = data.find(line);
        if (it != data.end()) {
          it->second++;
        }
        else {
          data[line] = 1;
        }
      }
    }
  }

  static void ReadFileMap(
    const std::string& path, std::map<std::string, int>& data) {
    std::ifstream in(path);
    std::string line1, line2;
    if (in) {
      while (std::getline(in, line1)) {
        std::getline(in, line2);
        data[line1] = atoi(line2.c_str());
      }
    }
  }

  static void WriteFileMap(
    const std::string& path, const std::map<std::string, int>& data) {
    std::ofstream out(path);
    for (auto it = data.begin();
      it != data.end(); ++it) {
      out << it->first << std::endl << it->second << std::endl;
    }
  }

  static void WriteFileSet(
    const std::string& path, const std::set<std::string>& data) {
    std::ofstream out(path);
    for (auto it = data.begin();
      it != data.end(); ++it) {
      out << *it << std::endl;
    }
  }
};
